package com.cardone.platform.usercenter.dao;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.Getter;
import lombok.Setter;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import com.cardone.common.dto.PaginationDto;
import com.cardone.context.Attributes;
import com.cardone.context.ContextHolder;
import com.cardone.persistent.builder.Model;
import com.cardone.persistent.builder.ModelArgs;
import com.cardone.persistent.builder.ModelUtils;
import com.cardone.persistent.support.JdbcTemplateSupport;
import com.cardone.persistent.support.PaginationArgs;
import com.cardone.persistent.support.SimpleJdbcDao;
import com.cardone.platform.usercenter.dto.UserDto;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 用户
 *
 * @author yaohaitao
 *
 */
@Getter
@Setter
public class UserJdbcDao extends SimpleJdbcDao<UserDto> implements UserDao {
	public UserJdbcDao() {
		this.deleteByIds = SqlIds.deleteByIds.id();

		this.find = SqlIds.find.id();

		this.findByCode = SqlIds.findByCode.id();

		this.findById = SqlIds.findById.id();

		this.findByLikeCode = SqlIds.findByLikeCode.id();

		this.insertByCode = SqlIds.insertByCode.id();

		this.insertByNotExistsCode = SqlIds.insertByNotExistsCode.id();

		this.readByCode = SqlIds.readByCode.id();

		this.readByLikeCode = SqlIds.readByLikeCode.id();

		this.updateByCode = SqlIds.updateByCode.id();
	}

	@Override
	public boolean isBlankById(final UserDto dto) {
		return StringUtils.isBlank(dto.getId());
	}

	@Override
	public void setId(final UserDto dto) {
		dto.setId(UUID.randomUUID().toString());
	}

	@Override
	public <P> P findByCodeForLogin(final Class<P> mappedClass, final UserDto findUser) {
		final Map<String, Object> model = Maps.newHashMap();

		model.put(Attributes.code.name(), findUser.getCode());

		return ContextHolder.getBean(JdbcTemplateSupport.class).find(mappedClass, SqlIds.findByCodeForLogin.id(), model);
	}

	@Override
	public UserDto findById(final String id) {
		final Map<String, Object> model = Maps.newHashMap();

		model.put(Attributes.id.name(), id);

		return ContextHolder.getBean(JdbcTemplateSupport.class).find(UserDto.class, SqlIds.findById.id(), model);
	}

	@Override
	public <P> PaginationDto<P> paginationByOrgIdAndLikeCode(final Class<P> mappedClass, final UserDto paginationUser) {
		final Model model = ModelUtils.newModel(new ModelArgs(paginationUser).setIsSimple(true));

		if (MapUtils.isNotEmpty(paginationUser.getAttrs())) {
			model.putAll(paginationUser.getAttrs());
		}

		return ContextHolder.getBean(JdbcTemplateSupport.class).pagination(mappedClass, new PaginationArgs(SqlIds.readByOrgIdAndLikeCode.id(), SqlIds.findByOrgIdAndLikeCode.id(), paginationUser), model);
	}

	@Override
	public int updateEndDateByIdForInvalid(final String id) {
		final Map<String, Object> model = Maps.newHashMap();

		model.put(Attributes.id.name(), id);

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateEndDateByIdForInvalid.id(), model);
	}

	@Override
	public int updateForBaseInfo(final UserDto updateUser, final Boolean updateMobilePhone) {
		final List<String> updatePropertieList = Lists.newArrayList();

		if (StringUtils.isNotBlank(updateUser.getCallName())) {
			updatePropertieList.add(UserDto.Attributes.callName.name());
		}

		if (StringUtils.isNotBlank(updateUser.getName())) {
			updatePropertieList.add(Attributes.name.name());
		}

		if (StringUtils.isNotBlank(updateUser.getSexId())) {
			updatePropertieList.add(UserDto.Attributes.sexId.name());
		}

		if (updateUser.getBirthday() != null) {
			updatePropertieList.add(UserDto.Attributes.birthday.name());
		}

		if (StringUtils.isNotBlank(updateUser.getMarryStateId())) {
			updatePropertieList.add(UserDto.Attributes.marryStateId.name());
		}

		if (BooleanUtils.isTrue(updateMobilePhone)) {
			updatePropertieList.add(UserDto.Attributes.mobilePhone.name());
		}

		if (StringUtils.isNotBlank(updateUser.getDiplomaId())) {
			updatePropertieList.add(UserDto.Attributes.diplomaId.name());
		}

		if (StringUtils.isNotBlank(updateUser.getFolkId())) {
			updatePropertieList.add(UserDto.Attributes.folkId.name());
		}

		final Model model = ModelUtils.newModel(new ModelArgs(Model.Keys.update.stringValue(), updateUser, updatePropertieList.toArray(ArrayUtils.EMPTY_STRING_ARRAY)));

		model.putExtend(null, Attributes.id.name(), null, updateUser.getId());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);
	}

	@Override
	public int updateForDetail(final UserDto updateUser) {
		final List<String> updatePropertieList = Lists.newArrayList();

		if (StringUtils.isNotBlank(updateUser.getCallName()) || StringUtils.isNotBlank(updateUser.getName())) {
			String name = com.cardone.common.util.StringUtils.defaultIfBlank(updateUser.getCallName(), updateUser.getName(), updateUser.getCode());

			updateUser.setName(name);
			updateUser.setCallName(name);

			updatePropertieList.add(UserDto.Attributes.callName.name());
			updatePropertieList.add(Attributes.name.name());
		}

		if (StringUtils.isNotBlank(updateUser.getSexId())) {
			updatePropertieList.add(UserDto.Attributes.sexId.name());
		}

		if (updateUser.getBirthday() != null) {
			updatePropertieList.add(UserDto.Attributes.birthday.name());
		}

		if (StringUtils.isNotBlank(updateUser.getMarryStateId())) {
			updatePropertieList.add(UserDto.Attributes.marryStateId.name());
		}

		if (StringUtils.isNotBlank(updateUser.getMobilePhone())) {
			updatePropertieList.add(UserDto.Attributes.mobilePhone.name());
		}

		if (StringUtils.isNotBlank(updateUser.getDiplomaId())) {
			updatePropertieList.add(UserDto.Attributes.diplomaId.name());
		}

		if (StringUtils.isNotBlank(updateUser.getFolkId())) {
			updatePropertieList.add(UserDto.Attributes.folkId.name());
		}

		if (StringUtils.isNotBlank(updateUser.getPassword())) {
			updatePropertieList.add(UserDto.Attributes.password.name());
		}

		if (StringUtils.isNotBlank(updateUser.getStateId())) {
			updatePropertieList.add(Attributes.stateId.name());
		}

		if (updateUser.getEndDate() != null) {
			updatePropertieList.add(Attributes.endDate.name());
		}

		if (StringUtils.isNotBlank(updateUser.getOrgId())) {
			updatePropertieList.add(Attributes.orgId.name());
		}

		updatePropertieList.add(UserDto.Attributes.address.name());
		updatePropertieList.add(UserDto.Attributes.age.name());
		updatePropertieList.add(UserDto.Attributes.companyName.name());
		updatePropertieList.add(UserDto.Attributes.email.name());
		updatePropertieList.add(UserDto.Attributes.flagId.name());
		updatePropertieList.add(UserDto.Attributes.intro.name());
		updatePropertieList.add(UserDto.Attributes.locus.name());
		updatePropertieList.add(UserDto.Attributes.professionId.name());
		updatePropertieList.add(UserDto.Attributes.telephone.name());

		updatePropertieList.add(UserDto.Attributes.countryId.name());
		updatePropertieList.add(UserDto.Attributes.provinceId.name());
		updatePropertieList.add(UserDto.Attributes.cityId.name());
		updatePropertieList.add(UserDto.Attributes.districtId.name());

		final Model model = ModelUtils.newModel(new ModelArgs(Model.Keys.update.stringValue(), updateUser, updatePropertieList.toArray(ArrayUtils.EMPTY_STRING_ARRAY)));

		model.putExtend(null, Attributes.id.name(), null, updateUser.getId());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);
	}

	@Override
	public int updateForFullInfo(final UserDto updateUser, final Boolean updateMobilePhone) {
		final List<String> updatePropertieList = Lists.newArrayList();

		if (StringUtils.isNotBlank(updateUser.getCallName()) || StringUtils.isNotBlank(updateUser.getName())) {
			String name = com.cardone.common.util.StringUtils.defaultIfBlank(updateUser.getCallName(), updateUser.getName(), updateUser.getCode());

			updateUser.setName(name);
			updateUser.setCallName(name);

			updatePropertieList.add(UserDto.Attributes.callName.name());
			updatePropertieList.add(Attributes.name.name());
		}

		if (StringUtils.isNotBlank(updateUser.getSexId())) {
			updatePropertieList.add(UserDto.Attributes.sexId.name());
		}

		if (updateUser.getBirthday() != null) {
			updatePropertieList.add(UserDto.Attributes.birthday.name());
		}

		if (StringUtils.isNotBlank(updateUser.getMarryStateId())) {
			updatePropertieList.add(UserDto.Attributes.marryStateId.name());
		}

		if (BooleanUtils.isTrue(updateMobilePhone)) {
			updatePropertieList.add(UserDto.Attributes.mobilePhone.name());
		}

		if (StringUtils.isNotBlank(updateUser.getDiplomaId())) {
			updatePropertieList.add(UserDto.Attributes.diplomaId.name());
		}

		if (StringUtils.isNotBlank(updateUser.getFolkId())) {
			updatePropertieList.add(UserDto.Attributes.folkId.name());
		}

		updatePropertieList.add(UserDto.Attributes.address.name());
		updatePropertieList.add(UserDto.Attributes.age.name());
		updatePropertieList.add(UserDto.Attributes.companyName.name());
		updatePropertieList.add(UserDto.Attributes.email.name());
		updatePropertieList.add(UserDto.Attributes.flagId.name());
		updatePropertieList.add(UserDto.Attributes.intro.name());
		updatePropertieList.add(UserDto.Attributes.locus.name());
		updatePropertieList.add(UserDto.Attributes.professionId.name());
		updatePropertieList.add(UserDto.Attributes.telephone.name());

		updatePropertieList.add(UserDto.Attributes.countryId.name());
		updatePropertieList.add(UserDto.Attributes.provinceId.name());
		updatePropertieList.add(UserDto.Attributes.cityId.name());
		updatePropertieList.add(UserDto.Attributes.districtId.name());

		final Model model = ModelUtils.newModel(new ModelArgs(Model.Keys.update.stringValue(), updateUser, updatePropertieList.toArray(ArrayUtils.EMPTY_STRING_ARRAY)));

		model.putExtend(null, Attributes.id.name(), null, updateUser.getId());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);
	}

	@Override
	public int updateMobilePhone(final String id, final String mobilePhone) {
		final Model model = ModelUtils.newModel();

		model.putExtend(null, Attributes.id.name(), null, id);
		model.putExtend(Model.Keys.update.stringValue(), UserDto.Attributes.mobilePhone.name(), null, mobilePhone);

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);
	}

	@Override
	public int updatePasswordById(final String id, final String oldPassword, final String newPassword) {
		final Model model = ModelUtils.newModel();

		model.putExtend(null, Attributes.id.name(), null, id);

		if (StringUtils.isNotBlank(oldPassword)) {
			model.putExtend(null, UserDto.Attributes.password.name(), null, oldPassword);
		}

		model.putExtend(Model.Keys.update.stringValue(), UserDto.Attributes.password.name(), null, newPassword);

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);
	}
}